#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <limits.h>

#define LEVEL_MIN 3
#define LEVEL_MAX 10

//记录的最长关数
#define MAX_STAGE 10

#define times() (sizeof(long) * CHAR_BIT)

/**
 * 睡眠指定毫秒
 * @param unsigned ms
 */
int sleep(unsigned ms)
{
    clock_t c1 = clock(), c2;
    do {
        if ((c2 = clock()) == (clock_t)-1)
            return 0;
    } while (1000.0 * (c2 - c1) / CLOCKS_PER_SEC < ms);

    return 1;
}

/**
 * 统计设置位
 * @param long digit
 */
int bit_count(long digit)
{
    int tmp=0;
    while (digit) {
        if (digit & 1) ++tmp;
        digit >>= 1;
    }

    return tmp;
}

/**
 * 生成随机数
 * 这里最大长度为10,完全可以用long型保存
 *
 * @param unsigned length
 */
char* makeRandNum(char *dest, unsigned length)
{
    dest[0] = '1' + rand() % 9;
    for (int i=1; i<length; i++) {
        dest[i] = '0' + rand() % 10;
    }

    return dest;
}

int main(void){
    //记录题目
    char subject[MAX_STAGE][LEVEL_MAX];

    //记录回答
    char reply[MAX_STAGE][LEVEL_MAX];

    //总得分(使用设置位)
    long unsigned score=0;

    //选择等级
    int level;

    int stage = 0;

    srand(time(NULL));


    printf("%10s%s\n","", "记忆力训练");
    puts("---------------------------");
    printf("最大关卡:%lu\n", times());
    printf("游戏记录保存最后进行的%d次\n", MAX_STAGE);
    puts("---------------------------");

    do {
        printf("要挑战的等级(%d~%d):", LEVEL_MIN, LEVEL_MAX);
        scanf("%d", &level);

    } while (level < LEVEL_MIN || level > LEVEL_MAX);


    do {
        char no[LEVEL_MAX], x[LEVEL_MAX];

        printf("第%d关开始\n", stage+1);

        sleep(1000);

        printf("%s ", makeRandNum(no, level));

        fflush(stdout);

        sleep(125 * level);

        printf("\r%*s\r", level + 1, "");

        printf("请输入刚才的数:");
        scanf("%s", x);

        if (!strcmp(no, x)) {
            puts("Right!");
            score |= (1 << stage);

        } else {
            puts("Wrong!");
        }

        strcpy(subject[stage % 10], no);

        strcpy(reply[stage % 10], x);


        //进行下一次
        ++stage;

        putchar('\n');

        //是否继续
        if ( stage <= times() - 1 && stage >= 10) {
            printf("是否继续? (Yes...1/No...0):");

            int retry = 0;

            fscanf(stdin, "%d", &retry);

            if (!retry) {
                break;
            }

        }


    } while (stage <= times() - 1);

    printf("%d题中您总共答对了%d题:", stage, bit_count(score));
    for (int i=0; i<stage; ++i) {
        printf("%c ", (score & (1 << i))? 'O': 'X');
    }

    putchar('\n');

    int review=0;

    printf("回顾答题过程(Yes...1/No...0):");

    scanf("%d", &review);

    putchar('\n');


    if (review) {

        char *s = "%5s%15s%15s%8s\n";

        printf(s, "no.", "question", "answer", "result");

        printf(s, "---", "--------", "------", "------");

        //最大下标(stage-1)前10个元素(stage -1 -9)
        int start = (stage >= MAX_STAGE)? (stage -10): 0;

        int len = MAX_STAGE;

        if (start > 0) {
            printf(s, "...", "...", "...", "...");
        }

        while (len--) {
            printf(
                "%5d%15s%15s%8c\n",

                start + 1,

                subject[start % 10],

                reply[start % 10],

                score & (1 << start) ? 'O': 'X'
                );
            ++start;
        }

    }

    printf("-----------end----------\n");

    return 0;
}
